Interacting with Metadata#
This tutorial walks through the process of interacting with metadata samples from CAD1. However, the same process can be applied to other challenges.
from pprint import pprint
Obtaining the sample data#
In order to demonstrate basic functionality, we will download a small demo dataset for CAD1.
!gdown 10SfuZR7yVlVO6RwNUc3kPeJHGiwpN3VS
!tar -xvf cadenza_data_demo.tar.xz
^C
Traceback (most recent call last):
File "/home/gerardoroadabike/anaconda3/envs/clarity39/bin/gdown", line 8, in <module>
sys.exit(main())
File "/home/gerardoroadabike/anaconda3/envs/clarity39/lib/python3.10/site-packages/gdown/cli.py", line 163, in main
download(
File "/home/gerardoroadabike/anaconda3/envs/clarity39/lib/python3.10/site-packages/gdown/download.py", line 157, in download
res = sess.get(url, stream=True, verify=verify)
File "/home/gerardoroadabike/anaconda3/envs/clarity39/lib/python3.10/site-packages/requests/sessions.py", line 602, in get
return self.request("GET", url, **kwargs)
File "/home/gerardoroadabike/anaconda3/envs/clarity39/lib/python3.10/site-packages/requests/sessions.py", line 589, in request
resp = self.send(prep, **send_kwargs)
File "/home/gerardoroadabike/anaconda3/envs/clarity39/lib/python3.10/site-packages/requests/sessions.py", line 703, in send
r = adapter.send(request, **kwargs)
File "/home/gerardoroadabike/anaconda3/envs/clarity39/lib/python3.10/site-packages/requests/adapters.py", line 667, in send
resp = conn.urlopen(
File "/home/gerardoroadabike/anaconda3/envs/clarity39/lib/python3.10/site-packages/urllib3/connectionpool.py", line 789, in urlopen
response = self._make_request(
File "/home/gerardoroadabike/anaconda3/envs/clarity39/lib/python3.10/site-packages/urllib3/connectionpool.py", line 536, in _make_request
response = conn.getresponse()
File "/home/gerardoroadabike/anaconda3/envs/clarity39/lib/python3.10/site-packages/urllib3/connection.py", line 464, in getresponse
httplib_response = super().getresponse()
File "/home/gerardoroadabike/anaconda3/envs/clarity39/lib/python3.10/http/client.py", line 1375, in getresponse
response.begin()
File "/home/gerardoroadabike/anaconda3/envs/clarity39/lib/python3.10/http/client.py", line 318, in begin
version, status, reason = self._read_status()
File "/home/gerardoroadabike/anaconda3/envs/clarity39/lib/python3.10/http/client.py", line 279, in _read_status
line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
File "/home/gerardoroadabike/anaconda3/envs/clarity39/lib/python3.10/socket.py", line 705, in readinto
return self._sock.recv_into(b)
File "/home/gerardoroadabike/anaconda3/envs/clarity39/lib/python3.10/ssl.py", line 1307, in recv_into
return self.read(nbytes, buffer)
File "/home/gerardoroadabike/anaconda3/envs/clarity39/lib/python3.10/ssl.py", line 1163, in read
return self._sslobj.read(len, buffer)
KeyboardInterrupt
tar: cadenza_data_demo.tar.xz: Cannot open: No such file or directory
tar: Error is not recoverable: exiting now
The Structure of the metadata#
In CAD1, there are two metadata files, which are JSON files. This structure is similar across all challenges. Some challenges may have additional metadata files.
listeners.json - listeners’ characteristics in form of audiograms for left and right ear.
musdb18hq.json - list of audio tracks to process.
Dataset |
Structure |
Index |
|---|---|---|
|
dict of dicts |
LISTENER_ID |
|
list of dict |
Track Name |
Reading the metadata files#
The challenges metadata are stored in JSON format. The python’s JSON library imports JSON files and parses them into python objects.
This is demonstrated in the cell below.
import json
with open("cadenza_data_demo/cad1/task1/metadata/listeners.valid.json") as f:
listeners = json.load(f)
with open("cadenza_data_demo/cad1/task1/metadata/musdb18.valid.json", "r", encoding="utf-8") as file:
song_data = json.load(file)
Listeners#
The next cell shows two samples of listeners from the validation set. These are anonymized real audiograms.
audiogram_cfsis a list of center frequencies in Hz.auidogram_levels_landaudiogram_levels_rare lists of hearing thresholds in dB SPL for the left and right ear, respectively.nameis the listener’s id.
pprint(listeners)
{'L5040': {'audiogram_cfs': [250, 500, 1000, 2000, 3000, 4000, 6000, 8000],
'audiogram_levels_l': [30, 25, 25, 70, 80, 80, 80, 80],
'audiogram_levels_r': [20, 15, 20, 45, 55, 70, 80, 80],
'name': 'L5040'},
'L5076': {'audiogram_cfs': [250, 500, 1000, 2000, 3000, 4000, 6000, 8000],
'audiogram_levels_l': [15, 20, 30, 30, 45, 50, 60, 75],
'audiogram_levels_r': [15, 25, 30, 35, 40, 40, 60, 70],
'name': 'L5076'}}
Music#
The next cell shows one samples of music tracks from the validation set. This file contains general information about the track like the name, split and licence.
pprint(song_data)
[{'Genre': 'Pop/Rock',
'License': 'Restricted',
'Source': 'DSD',
'Split': 'valid',
'Track Name': 'Actions - One Minute Smile'}]
Let’s load a 30-second sample of the mixture signal from the first song in the validation set.
import pandas as pd
from IPython.display import Audio
from pathlib import Path
from scipy.io import wavfile
# Load song_data as pandas DataFrame
songs_valid = pd.DataFrame.from_dict(song_data)
split_directory = (
"test"
if songs_valid.loc[0, "Split"] == "test"
else "train"
)
sample_rate, mixture_signal = wavfile.read(
Path('cadenza_data_demo/cad1/task1/audio/musdb18hq')
/ split_directory
/ songs_valid.loc[0, "Track Name"]
/ "mixture.wav"
)
# Take only 30 seconds
mixture_signal = mixture_signal[30*sample_rate:60*sample_rate, :]
Audio(mixture_signal.T, rate=sample_rate)